#include "liblicense.h"
#include "rc4.h"
#include "md5.h"

int GetRandomInt(int min, int max)
{
    // 使用当前时间作为种子
    srand(wxGetLocalTime());
    return min + (rand() % (max - min + 1));
}

CLicense::CLicense()
{
    m_tipStrings.push_back(wxT("晚上8点啦，记得让眼睛和大脑休息一下哦!"));
    m_tipStrings.push_back(wxT("忙碌一天辛苦了，8点后适当放松一下吧！"));
    m_tipStrings.push_back(wxT("时间不早啦，歇一歇，明天会更精神！"));
    m_tipStrings.push_back(wxT("晚上8点，是时候给自己一点放松时间了."));
    m_tipStrings.push_back(wxT("别忘了，8点后减少用眼，保护视力哦！"));
    m_tipStrings.push_back(wxT("休息是为了走更远的路，8点后记得放松."));
    m_tipStrings.push_back(wxT("夜深了，适当休息，明天继续加油！"));
    m_tipStrings.push_back(wxT("8点后，让身体和心灵都静下来吧."));
    m_tipStrings.push_back(wxT("今天的努力很棒，现在该休息一下啦！"));
    m_tipStrings.push_back(wxT("晚上8点，提醒你：放松时间到！"));
    m_tipStrings.push_back(wxT("8点啦！你的手机也需要“睡觉”充电啦."));
    m_tipStrings.push_back(wxT("警告！晚上8点后继续熬夜会触发“熊猫眼”模式！"));
    m_tipStrings.push_back(wxT("8点后还盯着屏幕？小心被“困”兽攻击哦！"));
    m_tipStrings.push_back(wxT("你的大脑发来消息：8点后请求进入待机模式."));
    m_tipStrings.push_back(wxT("8点啦，再不停工，你的床要抗议了！"));
    m_tipStrings.push_back(wxT("友情提示：8点后不休息，明天会变成“僵尸模式”！"));
    m_tipStrings.push_back(wxT("8点后还在工作？你的枕头表示很寂寞."));
    m_tipStrings.push_back(wxT("你的眼睛说：“8点了，求放过."));
    m_tipStrings.push_back(wxT("8点啦，再不休息，明天的你会恨现在的你！"));
    m_tipStrings.push_back(wxT("8点后还忙？小心被“困意”绑架！"));
    m_tipStrings.push_back(wxT("夜幕降临，8点已至，让疲惫随风而去."));
    m_tipStrings.push_back(wxT("8点的钟声轻轻响起，是时候让心灵小憩了."));
    m_tipStrings.push_back(wxT("夜晚温柔，8点提醒你：慢下来，享受宁静."));
    m_tipStrings.push_back(wxT("8点后的时光，属于放松与沉淀."));
    m_tipStrings.push_back(wxT("星光点点，8点已到，让忙碌暂歇."));
    m_tipStrings.push_back(wxT("8点，是夜晚给你的温柔提醒：该休息了."));
    m_tipStrings.push_back(wxT("让8点成为你今天的休止符，明天再谱新篇."));
    m_tipStrings.push_back(wxT("8点的风轻轻吹过，带来一丝倦意，该歇歇了."));
    m_tipStrings.push_back(wxT("夜晚8点，让身心回归平静."));
    m_tipStrings.push_back(wxT("8点，是时候放下一切，拥抱片刻安宁."));
}

CLicense::~CLicense()
{

}

/// 随机得到提示语
const wxString CLicense::getTipString(void)
{
    return m_tipStrings[GetRandomInt(0,m_tipStrings.size()-1)];
}

/// 检测系统是否授权
bool CLicense::isAuthorization(void)
{
    wxString authfilepath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+"/authorize.aut";

    if(!wxFileName::Exists(authfilepath))
    {
        // 生成授权文件
        this->generateAuthorizationFile();
        return false;
    }

    tagLicenseHearder pLicenseHearder;
    memset(&pLicenseHearder,0,sizeof(tagLicenseHearder));

    tagLicenseItem pdecLicenseItem;
    memset(&pdecLicenseItem,0,sizeof(tagLicenseItem));

    wxFile decfile;

    try
    {
        if (decfile.Open(authfilepath, wxFile::read))
        {
            // 写入结构体到文件
            if (decfile.Read(&pLicenseHearder, sizeof(tagLicenseHearder)) != sizeof(tagLicenseHearder))
            {
                decfile.Close();
                return false;
            }

            if(pLicenseHearder.mark[0] != 'A' ||
               pLicenseHearder.mark[1] != 'U' ||
               pLicenseHearder.mark[2] != 'T')
            {
                decfile.Close();
                return false;
            }

            if(pLicenseHearder.dataSize > 0)
            {
                wxMemoryBuffer pdecMemBuffer(sizeof(tagLicenseItem)*3);

                if (decfile.Read(pdecMemBuffer.GetData(), pLicenseHearder.dataSize) != pLicenseHearder.dataSize)
                {
                    decfile.Close();
                    return false;
                }

                if(Rc4Decrypt(RC4_KEY,
                           (unsigned char*)pdecMemBuffer.GetData(),
                           (unsigned char*)&pdecLicenseItem,
                           pLicenseHearder.dataSize) != sizeof(tagLicenseItem))
                {
                    decfile.Close();
                    return false;
                }
            }

            decfile.Close();
        }
    }
    catch (const std::exception& e) {
        if (decfile.IsOpened()) decfile.Close();
        wxLogError("Exception while processing license file: %s", e.what());
        return false;
    }

    try
    {
        int pdecStrIndex = -1;
        wxString pdecMuid = wxString(pdecLicenseItem.muid);
        int pos = pdecMuid.find_last_of("+");
        if(pos > 0)
            pdecMuid.Mid(pos+1,pdecMuid.length()).ToInt(&pdecStrIndex);

        // 如果文件中的uuid和当前机器的uuid不匹配也返回false
        if(!pdecMuid.Contains(this->GetMachineUniqueId()))
            return false;

        if(pdecStrIndex < 0 || pdecStrIndex >= m_tipStrings.size())
            return false;

        pdecMuid+=m_tipStrings[pdecStrIndex];
        wxString pdecMd5 = get_str_md5(pdecMuid);
        if(pdecMd5 != pdecLicenseItem.authcode)
            return false;
    }
    catch (const std::exception& e) {
        wxLogError("Exception during license validation: %s", e.what());
        return false;
    }

    return true;
}

/// 开始授权并保存到指定的文件
const tagLicenseItem* CLicense::startAuthorizationAndSaveFile(wxString muid,wxString authfilepath)
{
    if(muid == "" || authfilepath == "" || !wxFileName::Exists(authfilepath))
        return NULL;

    std::map<wxString,tagLicenseItem>::iterator iter = m_LicenseItems.find(muid);
    if(iter == m_LicenseItems.end())
        return NULL;

    int pdecStrIndex = -1;
    wxString pdecMuid = wxString((*iter).second.muid);
    int pos = pdecMuid.find_last_of("+");
    if(pos > 0)
        pdecMuid.Mid(pos+1,pdecMuid.length()).ToInt(&pdecStrIndex);

    if(pdecStrIndex < 0 || pdecStrIndex >= m_tipStrings.size())
        return NULL;

    pdecMuid+=m_tipStrings[pdecStrIndex];
    wxString pdecMd5 = get_str_md5(pdecMuid);
    if(pdecMd5 != "")
    {
        memcpy((*iter).second.authcode,pdecMd5.c_str(),pdecMd5.length());
        (*iter).second.authcode[pdecMd5.length()] = '\0';
        (*iter).second.authtime = wxDateTime::Now().GetTicks();

        wxFile file;
        if (file.Open(authfilepath, wxFile::write))
        {
            wxMemoryBuffer pdecMemBuffer(sizeof(tagLicenseItem)*3);
            int decSize = Rc4Encrypt(RC4_KEY,
                                     (unsigned char*)(&(*iter).second),
                                     (unsigned char*)pdecMemBuffer.GetData(),
                                     sizeof(tagLicenseItem));

            tagLicenseHearder pLicenseHearder;
            pLicenseHearder.dataSize = decSize;

            if (file.Write(&pLicenseHearder, sizeof(tagLicenseHearder)) == sizeof(tagLicenseHearder))
            {
                file.Write(pdecMemBuffer.GetData(), decSize);
            }

            file.Close();
        }

        return &(*iter).second;
    }

    return NULL;
}

/// 导入指定文件的授权文件到系统中
const tagLicenseItem* CLicense::loadAuthorizationFromFile(wxString authfilepath)
{
    // 如果授权文件存在，就不生成授权文件了
    if(!wxFileName::Exists(authfilepath))
        return NULL;

    tagLicenseHearder pLicenseHearder;
    memset(&pLicenseHearder,0,sizeof(tagLicenseHearder));

    tagLicenseItem pdecLicenseItem;
    memset(&pdecLicenseItem,0,sizeof(tagLicenseItem));

    wxFile file;
    if (file.Open(authfilepath, wxFile::read))
    {
        // 写入结构体到文件
        if (file.Read(&pLicenseHearder, sizeof(tagLicenseHearder)) != sizeof(tagLicenseHearder))
        {
            file.Close();
            return NULL;
        }

        if(pLicenseHearder.mark[0] != 'A' ||
            pLicenseHearder.mark[1] != 'U' ||
            pLicenseHearder.mark[2] != 'T')
        {
            file.Close();
            return NULL;
        }

        if(pLicenseHearder.dataSize > 0)
        {
            wxMemoryBuffer pdecMemBuffer(sizeof(tagLicenseItem)*3);

            if (file.Read(pdecMemBuffer.GetData(), pLicenseHearder.dataSize) != pLicenseHearder.dataSize)
            {
                file.Close();
                return NULL;
            }

            if(Rc4Decrypt(RC4_KEY,
                           (unsigned char*)pdecMemBuffer.GetData(),
                           (unsigned char*)&pdecLicenseItem,
                           pLicenseHearder.dataSize) != sizeof(tagLicenseItem))
            {
                file.Close();
                return NULL;
            }
        }

        file.Close();
    }

    std::map<wxString,tagLicenseItem>::iterator iter = m_LicenseItems.find(pdecLicenseItem.muid);
    if(iter != m_LicenseItems.end())
        return NULL;

    m_LicenseItems[pdecLicenseItem.muid] = pdecLicenseItem;

    return &m_LicenseItems[pdecLicenseItem.muid];
}

/// 生成授权文件
bool CLicense::generateAuthorizationFile(void)
{
    wxString authfilepath = wxFileName(wxStandardPaths::Get().GetExecutablePath()).GetPath()+"/authorize.aut";

    // 如果授权文件存在，就不生成授权文件了
    if(wxFileName::Exists(authfilepath))
        return false;

    tagLicenseItem pdecLicenseItem;
    memset(&pdecLicenseItem,0,sizeof(tagLicenseItem));

    wxString pdecMuid = wxString::Format("%s+%d",
                                         this->GetMachineUniqueId(),
                                         GetRandomInt(0,m_tipStrings.size()));
    std::string pMuid = pdecMuid.ToStdString();
    memcpy(&pdecLicenseItem.muid,pMuid.c_str(),pMuid.length());
    pdecLicenseItem.createtime = wxDateTime::Now().GetTicks();

    wxFile file;
    if (!file.Open(authfilepath, wxFile::write))
        return false;

    wxMemoryBuffer pdecMemBuffer(sizeof(tagLicenseItem)*3);
    int decSize = Rc4Encrypt(RC4_KEY,
                             (unsigned char*)(&pdecLicenseItem),
                             (unsigned char*)pdecMemBuffer.GetData(),
                             sizeof(tagLicenseItem));

    tagLicenseHearder pLicenseHearder;
    pLicenseHearder.dataSize = decSize;

    if (file.Write(&pLicenseHearder, sizeof(tagLicenseHearder)) != sizeof(tagLicenseHearder))
    {
        file.Close();
        return false;
    }

    if (file.Write(pdecMemBuffer.GetData(), decSize) != decSize)
    {
        file.Close();
        return false;
    }

    file.Close();

    m_LicenseItems[pdecMuid] = pdecLicenseItem;

    return true;
}

/// 添加一个授权到系统中
bool CLicense::addAuthorization(tagLicenseItem pLicenseItem)
{
    std::map<wxString,tagLicenseItem>::iterator iter = m_LicenseItems.find(pLicenseItem.muid);
    if(iter != m_LicenseItems.end())
        return false;

    m_LicenseItems[pLicenseItem.muid] = pLicenseItem;

    return true;
}

/// 更新授权
bool CLicense::updateAuthorization(tagLicenseItem pLicenseItem)
{
    if(m_LicenseItems.empty()) return false;

    std::map<wxString,tagLicenseItem>::iterator iter = m_LicenseItems.find(pLicenseItem.muid);
    if(iter == m_LicenseItems.end())
        return false;

    m_LicenseItems[pLicenseItem.muid] = pLicenseItem;

    return true;
}

/// 删除授权
void CLicense::deleteAuthorization(wxString Muid)
{
    if(m_LicenseItems.empty() || Muid == "")
        return;

    std::map<wxString,tagLicenseItem>::iterator iter = m_LicenseItems.find(Muid);
    if(iter != m_LicenseItems.end())
        m_LicenseItems.erase(iter);
}

/// 删除授权
void CLicense::deleteAuthorizations(wxArrayString autArray)
{
    if(autArray.IsEmpty()) return;

    for(int i=0;i<autArray.size();i++)
    {
        std::map<wxString,tagLicenseItem>::iterator iter = m_LicenseItems.find(autArray[i]);
        if(iter != m_LicenseItems.end())
            m_LicenseItems.erase(iter);
    }
}

/// 得到指定muid的授权
const tagLicenseItem* CLicense::getAuthorization(wxString autName)
{
    if(autName == "" || m_LicenseItems.empty()) return NULL;

    std::map<wxString,tagLicenseItem>::iterator iter = m_LicenseItems.find(autName);
    if(iter != m_LicenseItems.end())
        return &(*iter).second;

    return NULL;
}

/// 得到机器唯一ID
wxString CLicense::GetMachineUniqueId()
{
    std::stringstream uniqueInfo;

// 1. 收集平台特定信息
#ifdef _WIN32
        // Windows - 获取MAC地址
    IP_ADAPTER_INFO adapterInfo[16];
    DWORD dwBufLen = sizeof(adapterInfo);

    if (GetAdaptersInfo(adapterInfo, &dwBufLen) == ERROR_SUCCESS)
    {
        PIP_ADAPTER_INFO pAdapterInfo = adapterInfo;
        if (pAdapterInfo)
        {
            for (UINT i = 0; i < pAdapterInfo->AddressLength; i++)
            {
                uniqueInfo << std::hex << std::setw(2) << std::setfill('0')
                << (int)pAdapterInfo->Address[i];
            }
        }
    }

    // Windows - 获取计算机名
    char computerName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD size = sizeof(computerName);
    if (GetComputerNameA(computerName, &size))
    {
        uniqueInfo << computerName;
    }

#elif defined(__linux__)
        // Linux - 读取机器ID
    std::ifstream ifs("/etc/machine-id");
    if (ifs.good())
    {
        std::string machineId;
        std::getline(ifs, machineId);
        uniqueInfo << machineId;
    }
    else
    {
        // 回退方案 - 读取DMI信息
        std::ifstream dmi("/sys/class/dmi/id/product_uuid");
        if (dmi.good())
        {
            std::string productUuid;
            std::getline(dmi, productUuid);
            uniqueInfo << productUuid;
        }
    }

    // Linux - 获取主机名
    char hostname[256];
    if (gethostname(hostname, sizeof(hostname)) == 0)
    {
        uniqueInfo << hostname;
    }

#elif defined(__APPLE__)
        // macOS - 获取硬件UUID
    char hwUUID[256];
    size_t len = sizeof(hwUUID);
    if (sysctlbyname("hw.machine", hwUUID, &len, NULL, 0) == 0)
    {
        uniqueInfo << hwUUID;
    }

    // macOS - 获取序列号
    char serialNumber[256];
    len = sizeof(serialNumber);
    if (sysctlbyname("hw.serialno", serialNumber, &len, NULL, 0) == 0)
    {
        uniqueInfo << serialNumber;
    }
#endif

    // 2. 添加跨平台信息
    uniqueInfo << wxGetOsDescription().ToStdString();
    uniqueInfo << wxGetCpuArchitectureName().ToStdString();

    // 3. 计算SHA256哈希
    std::string infoStr = uniqueInfo.str();
    if (infoStr.empty())
    {
        // 如果无法获取任何信息，使用随机值作为回退
        infoStr = "fallback-unique-identifier-" + std::to_string(time(nullptr));
    }

    // 使用C++标准库的哈希函数
    std::hash<std::string> hasher;
    size_t hash = hasher(infoStr);

    // 转换为16进制字符串
    std::stringstream hashStream;
    hashStream << std::hex << hash;

    return wxString(hashStream.str());
}

